package com.link_with_health.webSocket;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.*;

@Component
@ServerEndpoint("/notification/{userId}")
public class NotificationServer {
    private static final Logger logger = LoggerFactory.getLogger(NotificationServer.class);
    private Session session;

    //private static ConcurrentHashMap<NotificationServer> webSockets =new ConcurrentHashMap<>();
    private static ConcurrentHashMap<String,Session> sessionPool = new ConcurrentHashMap<String,Session>();



    private String userId = "";

    @OnOpen
    public void onOpen(Session session, @PathParam("userId") String userId) {
        this.userId = userId;

        this.session = session;
        sessionPool.put(userId, session);
        logger.info("[--- user: "+userId +"notification start up---]");
    }


    @OnMessage
    public void onMessage(String message, @PathParam("userId") String userId) {
        try {
            this.sendMessage(message, userId);
        } catch (IOException e) {
            logger.error(message,e);
        }
    }

    @OnError
    public void onError(Session session, Throwable error
            , @PathParam("userId") String userId) {


        System.out.println("连接异常...");
        logger.error("[connect exception "+userId+" ]",error);
        error.printStackTrace();
    }

    @OnClose
    public void onClose(Session session
            , @PathParam("userId") String userId) {
        logger.info( "[--- user: "+ userId +" notification offline---]");
        //移除会话消息
        if(sessionPool.containsKey(userId)) {
            sessionPool.remove(userId);
            logger.info("[ " + userId +" ] " );
        }
        else
            logger.warn("[can't find user "
                    + userId + " in notificationServer ]");
    }

    /**
     * 发送消息
     * @param message json字符串
     * @param userId 接收者id
     * @throws IOException 异常
     */
    private void sendMessage(String message, String userId) throws IOException{
         Session receiverSession = sessionPool.get(userId);
         if(receiverSession != null) {
             logger.info("[ "+this.userId+" send message to "
                     + userId + " ]");
             receiverSession.getBasicRemote().sendText(message);
         }else
             logger.warn("[missing userId session=>"+ userId+" ]");
    }

    /**
     * 发送消息--在类外调用
     * @param message json字符串
     * @param userId 接收者id
     * @throws IOException
     */
    public static void sendMessageInController(String message, String userId) throws IOException {
        Session receiverSession = sessionPool.get(userId);
        if(receiverSession != null){
            receiverSession.getBasicRemote().sendText(message);
            logger.info("[send message to "+userId+"]");
        }else
            logger.warn("[userId not on line]");
    }

    /**
     * 发送所有人
     * @param message
     * @throws IOException 异常
     */
    public static void sendMessageForAll(String message)
            throws IOException{
        Iterator<Map.Entry<String,Session>> iterator = sessionPool
                .entrySet().iterator();
        while(iterator.hasNext()){
            Map.Entry<String,Session> entry = iterator.next();
            if(! entry.getValue().isOpen())
                entry.getValue().getBasicRemote().sendText(message);
            else{
                logger.warn("[user not in line "+ entry.getKey()
                        +" ]");
                continue;
            }
            logger.info("[send for "+entry.getKey()+" ]");
        }

    }
}
